package com.dlc.felear.xiaoensale.deviceControlSf;

import android.text.TextUtils;
import android.util.Log;

import com.dlc.felear.xiaoensale.constant.Constant;
import com.dlc.felear.xiaoensale.dlc_serial_port.DlcSerialPortClient;
import com.dlc.felear.xiaoensale.entity.HotInfo;
import com.dlc.felear.xiaoensale.factory.CmdList;
import com.dlc.felear.xiaoensale.helper.Session;
import com.dlc.felear.xiaoensale.utils.HexUtil;

import org.simple.eventbus.EventBus;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class HotControl {
    private static final String TAG = "HotControl";
    private static final int POWERSIZE = 1;
    private String serialNum;
    private ScheduledExecutorService scheduledThreadPool;
    private static HotControl instance;
    private int powerValue;
    private int temperatureValue;
    private int xpTemp = 0;
    private int realPowerValue;
    private float bcxs = 1.0f;
    private boolean ccFlag = false;
    private boolean isWork = false;
    private boolean wdbcFlag = false;
    private int tempCode;
    private Session session;
    private final int MAX_HOT_VALUE = 125;
    /**
     * 控制下料时是否加热
     */
    private boolean autoJr = true;

    public void setAutoJr(boolean autoJr){
        this.autoJr=autoJr;
        log("autoJr:"+this.autoJr);
    }

    private HotControl(String serialNum) {
        this.scheduledThreadPool = new ScheduledThreadPoolExecutor(1);
        this.serialNum = serialNum;
        session = Session.getSession();
        initValue();
        startTimer();
    }

    private void initValue() {
        try {
            bcxs = Float.parseFloat(session.getString(Constant.WEN_DU_XI_SHU, "1").trim());
        } catch (Exception e) {
            bcxs = 1.0f;
        }
        log("温度补偿系数:" + bcxs + " 补偿功能开启:" + wdbcFlag);
    }


    public static HotControl getInstance(String serialNum) {
        if (instance == null) {
            synchronized (HotControl.class) {
                if (instance == null) {
                    instance = new HotControl(serialNum);
                }
            }
        }
        return instance;
    }

    private void startTimer() {
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    loopRun();
                } catch (Exception e) {
                    log(e.getMessage());
                }
            }
        }, 1000, 1000, TimeUnit.MILLISECONDS);
    }

    private void loopRun() {
        sendCmd(CmdList.DcHotStatusNew());
    }

    /**
     * 接收设置档位指令
     *
     * @param power
     * @param temperature
     */
    public void setLevel(int power, int temperature) {
        if (power < 0) {
            power = 256 + power;
        }
        initWorkStatus(power);
        powerValue = (power * POWERSIZE);
        temperatureValue = temperature;
        if (temperatureValue > 130) {
            showToastMsg("设置温度过高,不能超过：" + Constant.MAX_HOT_TEMPER + "度");
            return;
        }
        if (wdbcFlag) {
            temperatureValue = (int) (temperatureValue + temperatureValue * bcxs);
        }
//        log("设置温度=" + temperature + " 功率=" + powerValue + " 补偿后=" + temperatureValue + " 补偿系数：" + bcxs);
        setHotValue(powerValue, temperatureValue);
    }


    public void pauseHot(int flag) {
        if (autoJr && ccFlag && flag == 0) {
            log("停止加热：" + powerValue + "_" + temperatureValue);
            setHotValue(0, 0);
        } else if (autoJr && ccFlag) {
            setHotValue(powerValue, temperatureValue);
            log("恢复加热" + powerValue + "_" + temperatureValue);
        }
    }

    private void initWorkStatus(int power) {
        if (power <= 0) {
            isWork = false;
        } else if (power > 0) {
            isWork = false;
        }
    }

    /**
     * 设置档位
     *
     * @param powerValue
     * @param temperatureValue
     */
    private void setHotValue(int powerValue, int temperatureValue) {
        if (powerValue < 0 || temperatureValue < 0) {
            log("控制加热参数异常:powerValue=" + powerValue + " temperatureValue=" + temperatureValue);
            return;
        }
        log("设定功率:" + powerValue + " 设定温度:" + temperatureValue);
        sendCmd(CmdList.setDcHotNew(powerValue, temperatureValue));
    }

    /**
     * 获取线盘温度
     *
     * @param data
     */
    public void recievePowerData(byte[] data) {
//        Log.e(TAG,"recievePowerData:"+HexUtil.bytes2HexString(data));
        if (CmdList.checkSum16(data)&&data[0] == (byte) 0xab && data.length > 5) {
            int power = ((data[4] & 0xff) << 8) | (data[5] & 0xff);
            int temp = ((data[6] & 0xff) << 8) | (data[7] & 0xff);
            byte error = data[8];
            realPowerValue = power;
            xpTemp = temp;
            if (wdbcFlag && bcxs != 1) {
                xpTemp = (int) (temp - bcxs * temp);
            }
            tempCode = error;
            controlLimitHot(temp);
            sendInfo();
        } else {
            Log.e(TAG, "检验失败:" + HexUtil.bytes2HexString(data));
        }
    }
    public void recievePowerDataNew(byte[] data) {
//        十六进制：ab 00 01 05 00 08 04 55 00 00 67
//        帧头(0xab)-目的地址(0x00)-源地址(0x01)-数据长度(0x05)-读数据(0x00)-工作档位(0x08)-最大功率（0x04代表8KW）-锅底温度( 0x55)-故障代码(0x00)-累加和校验码(0x00 0x67)
//        数据帧说明：电磁炉(0x01)当前运行的档位0x08=8档，最大功率8KW,当前锅底温度0x55=85℃，故障状态0x00=无故障。
        Log.e(TAG,"recievePowerData:"+HexUtil.bytes2HexString(data));
        if (CmdList.checkSum16(data)&&data[0] == (byte) 0xab) {
            int power = data[5];
            int temp = data[7];
            byte error = data[8];
            realPowerValue = power;
            xpTemp = temp;
            if (wdbcFlag && bcxs != 1) {
                xpTemp = (int) (temp - bcxs * temp);
            }
            tempCode = error;
            controlLimitHot(temp);
            sendInfo();
        } else {
            Log.e(TAG, "检验失败:" + HexUtil.bytes2HexString(data));
        }
    }

    private void controlLimitHot(int temp) {
        if (temp > MAX_HOT_VALUE) {
            setHotValue(0, 0);
            EventBus.getDefault().post("线盘温度超过保护温度", Constant.DEVICE_STATUS_MSG_SHOW);
        }
    }

    /**
     * 通过线盘温度
     *
     * @param maxValue
     * @param avgValue
     * @param minValue
     */
    public void recieveTemperatureData(int maxValue, int avgValue, int minValue) {
        log("maxValue=" + maxValue + " avgValue=" + avgValue + " minValue=" + minValue);

    }

    private void sendInfo() {
        EventBus.getDefault().post(new HotInfo(realPowerValue / POWERSIZE, xpTemp, getXpMsg()),
                Constant.ACTION_HOT_INFO_RESULT);
    }

    /**
     * 向下位机发送控制指令
     *
     * @param setDcHot
     */
    private void sendCmd(byte[] setDcHot) {
        DlcSerialPortClient.getInstance().send(serialNum, setDcHot);
    }

    /**
     * 转换错误码
     *
     * @param error
     * @return
     */
    public String getErrorString(int error) {
        String temp = "待机";
        switch (error) {
            case 0:
                temp = "正常";
                break;
            case 1:
                temp = "无锅";
                break;
            case 2:
                temp = "线盘超温";
                break;
            case 3:
                temp = "线盘温度探头开路";
                break;
            case 4:
                temp = "IGBT超温";
                break;
            case 5:
                temp = "IGBT温度探头开路";
                break;
            case 6:
                temp = "锅超温";
                break;
            case 7:
                temp = "锅温度探头开路";
                break;
            case 8:
                temp = "输入电压过低(缺相)";
                break;
            case 9:
                temp = "输入电压过高";
                break;
            case 10:
                temp = "输出电流故障";
                break;
            case 11:
                temp = "IGBT故障";
                break;
            case 12:
                temp = "负载故障(错锅)";
                break;
            case 13:
                temp = "火力开关故障";
                break;
            case 14:
                temp = "火力开关故障";
                break;
            case 15:
                temp = "环境温度过高";
                break;
            case 16:
                temp = "硬件故障";
                break;
        }
        return temp;
    }

    /**
     * 控制加热
     *
     * @param flag
     */
    public void startAndClosedHot(boolean flag) {
        if (!isWork || !ccFlag) {
            log("ccFlag=" + ccFlag + " isWork=" + isWork);
            return;
        }
        if (flag) {
            log("加食材完成，开始加热");
            setHotValue(powerValue, temperatureValue);
        } else {
            log("转到加食材，防止糊锅，停止加热");
            setHotValue(powerValue / 2, temperatureValue / 2);
        }
    }

    /**
     * 设置炒菜状态标志
     *
     * @param flag
     */
    public void setCcFlag(boolean flag) {
        ccFlag = flag;
        setHotValue(0, 0);
    }

    private String getXpMsg() {
        if (tempCode != 0) {
            return getErrorString(tempCode);
        }
        return ("线盘温度:" + xpTemp);
    }

    /**
     * 输出信息
     *
     * @param msg
     */
    private void log(String msg) {
        if (!TextUtils.isEmpty(msg)) {
            Log.e(TAG, msg);
        }
    }

    public void allStop() {
        sendCmd(CmdList.setDcHot(0, 0));
    }

    private void showToastMsg(String msg) {
        EventBus.getDefault().post(msg, Constant.DEVICE_STATUS_MSG_SHOW);
    }
}
